#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <X11/Xlib.h>
#include <Imlib2.h>

// --------------------------
// 核心功能: 根据图片路径设置桌面背景
// --------------------------
static int set_background(const char *image_path)
{
    // 步骤1: 验证图片路径是否存在且有效
    struct stat file_stat;
    if (stat(image_path, &file_stat) != 0) // 获取文件状态
    {
        fprintf(stderr, "❌ 错误: 未找到图片: %s\n", image_path);
        fprintf(stderr, "       原因: %s\n", strerror(errno));
        return 1;
    }
    if (!S_ISREG(file_stat.st_mode)) // 检查是否为普通文件
    {
        fprintf(stderr, "❌ 错误: '%s' 不是一个有效的文件\n", image_path);
        return 1;
    }

    // 步骤2: 初始化X11显示连接
    Display *dpy = XOpenDisplay(NULL); // 打开默认显示设备
    if (!dpy)
    {
        fprintf(stderr, "❌ 错误: 无法打开X11显示设备\n");
        return 1;
    }

    // 步骤3: 获取屏幕尺寸(用于正确缩放图片)
    int screen = DefaultScreen(dpy);                    // 获取默认屏幕
    Window root_win = RootWindow(dpy, screen);          // 获取根窗口(桌面背景窗口)
    unsigned int screen_w = DisplayWidth(dpy, screen);  // 屏幕宽度
    unsigned int screen_h = DisplayHeight(dpy, screen); // 屏幕高度

    // 步骤4: 初始化Imlib2(用于图片加载和缩放)
    imlib_context_set_display(dpy);                           // 关联X11显示
    imlib_context_set_visual(DefaultVisual(dpy, screen));     // 设置视觉属性
    imlib_context_set_colormap(DefaultColormap(dpy, screen)); // 设置颜色映射
    imlib_context_set_drawable(root_win);                     // 设置绘制目标为根窗口
    imlib_context_set_blend(0);                               // 禁用混合模式以提高性能

    // 步骤5: 加载图片
    Imlib_Image img = imlib_load_image(image_path); // 加载图片文件
    if (!img)
    {
        fprintf(stderr, "❌ 错误: 无法加载图片: %s\n", image_path);
        XCloseDisplay(dpy); // 关闭X11连接
        return 1;
    }
    imlib_context_set_image(img); // 将加载的图片设为当前操作对象

    // 步骤6: 缩放图片以匹配屏幕分辨率
    Imlib_Image scaled_img = imlib_create_cropped_scaled_image(
        0, 0,                     // 源图片起始坐标(左上角)
        imlib_image_get_width(),  // 源图片宽度
        imlib_image_get_height(), // 源图片高度
        screen_w, screen_h        // 目标尺寸(屏幕宽高)
    );
    if (!scaled_img)
    {
        fprintf(stderr, "❌ 错误: 无法缩放图片\n");
        imlib_free_image(); // 释放原始图片资源
        XCloseDisplay(dpy);
        return 1;
    }
    imlib_context_set_image(scaled_img); // 将缩放后的图片设为当前操作对象

    // 步骤7: 创建X11像素图(设置桌面背景必需)
    Pixmap bg_pixmap = XCreatePixmap(
        dpy, root_win,
        screen_w, screen_h,
        DefaultDepth(dpy, screen)); // 与屏幕同深度
    if (bg_pixmap == None)          // 检查像素图创建是否成功
    {
        fprintf(stderr, "❌ 错误: 无法创建背景像素图\n");
        imlib_free_image(); // 释放缩放后的图片
        imlib_context_set_image(img);
        imlib_free_image(); // 释放原始图片
        XCloseDisplay(dpy);
        return 1;
    }

    // 步骤8: 将缩放后的图片绘制到像素图
    imlib_context_set_drawable(bg_pixmap); // 切换绘制目标为像素图
    imlib_render_image_on_drawable(0, 0);  // 从左上角开始绘制

    // 步骤9: 将像素图设置为根窗口背景
    XSetWindowAttributes win_attrs;
    win_attrs.background_pixmap = bg_pixmap; // 设置背景像素图属性
    XChangeWindowAttributes(
        dpy, root_win,
        CWBackPixmap, // 仅更新背景像素图属性
        &win_attrs);
    XClearWindow(dpy, root_win); // 刷新根窗口使更改生效
    XFlush(dpy);                 // 确保所有X11命令立即发送

    // 步骤10: 清理资源(避免内存泄漏)
    XFreePixmap(dpy, bg_pixmap); // 释放像素图
    imlib_free_image();          // 释放缩放后的图片
    imlib_context_set_image(img);
    imlib_free_image(); // 释放原始图片
    XCloseDisplay(dpy); // 关闭X11连接

    // 成功提示
    printf("✅ 成功! 桌面背景已设置为: %s\n", image_path);
    return 0;
}

// --------------------------
// 主函数: 从标准输入读取图片路径
// --------------------------
int main(int argc, char **argv)
{
    (void)argc;
    // 存储图片路径的缓冲区(支持最长1024字符的路径)
    char image_path[1024] = {0};

    // 步骤1: 从标准输入读取图片路径(类似xclip读取文本的方式)
    // - 读取直到换行符或文件结束
    // - 过长路径会被截断以避免缓冲区溢出
    if (!fgets(image_path, sizeof(image_path), stdin))
    {
        if (feof(stdin)) // 标准输入为空
        {
            fprintf(stderr, "❌ 错误: 未收到输入(标准输入为空)\n");
            fprintf(stderr, "       使用方法: echo \"/完整/图片/路径.png\" | %s\n", argv[0]);
        }
        else // 读取失败
        {
            fprintf(stderr, "❌ 错误: 无法从标准输入读取: %s\n", strerror(errno));
        }
        return 1;
    }

    // 步骤2: 清理输入(移除末尾的换行符/回车符)
    size_t newline_pos = strcspn(image_path, "\n\r"); // 查找换行符位置
    image_path[newline_pos] = '\0';                   // 替换为字符串结束符

    // 步骤3: 检查清理后的输入是否为空
    if (image_path[0] == '\0')
    {
        fprintf(stderr, "❌ 错误: 空输入(未提供图片路径)\n");
        fprintf(stderr, "       使用方法: echo \"/完整/图片/路径.png\" | %s\n", argv[0]);
        return 1;
    }

    // 步骤4: 设置桌面背景
    return set_background(image_path);
}
